<template>
	<div>
		<div class="toolbar mt-2">
			<a-form ref="searchRef" :model="searchState" :label-col="{ style: { width: '80px' } }" @finish="current = 1">
				<a-row :gutter="20">
					<a-col :md="12" :lg="8" :xl="6">
						<a-form-item label="名称" class="mb-0">
							<a-input v-model:value="searchState['name']" placeholder="请输入" allow-clear></a-input>
						</a-form-item>
					</a-col>
					<a-col :md="12" :lg="8" :xl="6">
						<a-space>
							<a-button type="primary" html-type="submit">
								<search-outlined />搜索
							</a-button>

							<a-button v-permission="184" type="primary" @click="addRole">
								<plus-outlined />添加
							</a-button>
							<a-button v-permission="186" danger :disabled="!selectedRowKeys.length" @click="deleteRole">
								<delete-outlined />删除
							</a-button>
						</a-space>
					</a-col>
				</a-row>
			</a-form>
		</div>

		<div class="container mt-2">
			<a-table row-key="id" :row-selection="{ selectedRowKeys: selectedRowKeys, onChange: changeSelectedRowKeys }" :data-source="roleSource" :pagination="pagination" :loading="loading" :columns="columns" @change="initData">
				<template #bodyCell="{ column, record }">
					<template v-if="column.key === 'operation'">
						<a-space>
							<a-button v-permission="185" type="link" @click="editRole(record)">
								<edit-outlined />修改
							</a-button>
							<a-button v-permission="186" type="link" style="color:#ff7875" @click="deleteRole(record.id)">
								<delete-outlined />删除
							</a-button>
						</a-space>
					</template>
				</template>
			</a-table>
		</div>

		<a-modal v-model:visible="visible" title="角色信息" :width="500">
			<a-form ref="formRef" :model="formState" :rules="formRules" layout="horizontal" v-bind="{ labelCol: { style: { width: '80px' } } }">
				<a-form-item label="名称" name="name">
					<a-input v-model:value="formState.name" />
				</a-form-item>

				<a-form-item label="模块" name="auth">
					<a-tree v-model:checkedKeys="authCheckedKeys" checkable :height="360" :tree-data="moduleTree" :block-node="true" :field-names="{ key: 'id' }" :check-strictly="true" @check="checkAuthCheckedKeys">
						<template #title="{ title }">{{ title }}</template>
					</a-tree>
				</a-form-item>
			</a-form>

			<template #footer>
				<a-space>
					<a-button @click="visible = false">关闭</a-button>
					<a-button type="primary" @click="saveRole">提交</a-button>
				</a-space>
			</template>
		</a-modal>
	</div>
</template>
<script setup lang="jsx">
import dayjs from 'dayjs';

import { SearchOutlined, UpOutlined, DownOutlined, EditOutlined, DeleteOutlined, PlusOutlined } from "@ant-design/icons-vue";

import { reactive, ref, computed, getCurrentInstance, toRaw } from "vue";

const { proxy } = getCurrentInstance();

import { post, postJson, treeToList } from "../utils";
import { usePagination } from "vue-request";

//import { Upload } from '../components';

const searchRef = ref();
const searchState = reactive({});

const tableScroll = computed(() => ({ x: document.documentElement.clientWidth - 210 }));

const columns = [
	{
		title: "ID",
		dataIndex: "id",
		key: "id",
		width: 80,
		align: 'center',
		fixed: "left"
	},
	{
		title: "名称",
		dataIndex: "name",
		sorter: false,
		fixed: "left",
		width: 250,
		customRender: ({ text, record, index, column }) => {
			return record.name;
		}
	},
	{
		title: "权限",
		dataIndex: "auth",
		sorter: false,
		ellipsis: true,
		width: 1100,
		customRender: ({ text, record, index, column }) => {
			const titles = record.auth?.filter(({ type }) => type === 1).map((d) => d.title);

			return <a-tooltip placement="topLeft" title={titles.join(',')}>
				{titles.map((title) => <a-tag>{title}</a-tag>)}
			</a-tooltip>
		}
	},
	{},
	{
		title: "操作",
		key: "operation",
		sorter: false,
		fixed: "right",
		width: 160,
		align: "center"
	}
];

const selectedRowKeys = ref([]);

const changeSelectedRowKeys = keys => {
	selectedRowKeys.value = keys;
};

const { data, loading, run, current, pageSize, total } = usePagination(params => post("role", { ...params, ...searchState }), {
	defaultParams: [
		{
			page_size: 20
		}
	],
	pagination: {
		currentKey: "page",
		pageSizeKey: "page_size",
		totalKey: "total"
	}
});

const roleSource = computed(() => data.value?.data || []);
const pagination = computed(() => ({
	total: total.value,
	current: current.value,
	pageSize: pageSize.value
}));

const initData = (pag, filters, sorter) => {
	pag = Object.assign({
		current: current.value,
		pageSize: pageSize.value
	}, pag || {});
	filters = { ...filters, ...searchState };

	run({
		page_size: pag?.pageSize,
		page: pag?.current,
		sort_field: sorter?.field,
		sort_order: sorter?.order,
		...filters
	});
};

const deleteRole = (id) => {
	if (typeof id === "object") id = selectedRowKeys.value.join(",");
	if (!id) {
		proxy.$message.error("请选择需要删除的角色");
		return;
	}

	proxy.$confirm({
		title: "确认提示",
		content: `确定要删除${typeof id === "number" ? "当前" : "选中"}的角色吗？`,
		okText: "确认",
		cancelText: "取消",
		onOk() {
			post("role/delete", { id }).then(() => {
				proxy.$message.success("角色删除成功");

				//最后一条记录删除后需要返回上一页
				current.value = roleSource.value.length === 1 ? Math.max(current.value - 1, 1) : current.value;
			});
		}
	});
}

const visible = ref(false);
const formState = ref({});
const formRef = ref();

const formRules = computed(() => {
	const { password } = formState.value;

	return {
		name: [{ required: true, message: "请输入角色名称", trigger: "blur" }]
	}
});

const addRole = () => {
	formRef.value?.clearValidate();
	visible.value = true;
	formState.value = {};
}

const editRole = (record) => {
	formRef.value?.clearValidate();

	visible.value = true;
	const data = { ...record };
	authCheckedKeys.value = {
		checked: data.auth?.map(({ key }) => parseInt(key)) || []
	};
	formState.value = data;
}

const saveRole = () => {
	formRef.value
		.validate()
		.then(() => {
			proxy.$message.destroy();

			const params = { ...formState.value };

			if (!authCheckedKeys.value.checked.length) {
				params.auth = '[]';
			} else {
				const moduleList = treeToList(JSON.parse(JSON.stringify(moduleTree.value)));
				params.auth = JSON.stringify(
					moduleList
						.filter(({ id }) => {
							return authCheckedKeys.value.checked.includes(id);
						})
						.map(({ id, title, type, name }) => {
							const key = parseInt(id);
							return {
								key,
								title,
								type,
								name
							}
						})
				)
			}

			postJson('role/save', params).then(() => {
				proxy.$message.success('角色信息提交成功', 1);
				visible.value = false;

				current.value = !params.id && roleSource.value.length === pageSize.value ? Math.max(current.value + 1, 1) : current.value;
			}).catch((err) => {
				proxy.$message.error(err);
			});
		})
		.catch(err => {
		});
}

const moduleTree = ref([]);
post('module/tree').then((data) => {
	moduleTree.value = data;
});

const authCheckedKeys = ref([]);
const checkAuthCheckedKeys = (checkedKeys, { checked, checkedNodes, node }) => {
	//获取当前节点的所有子节点
	const nodes = treeToList([JSON.parse(JSON.stringify(node.dataRef))]);

	if (checked) {
		authCheckedKeys.value.checked = [...new Set(authCheckedKeys.value.checked.concat(nodes.map((d) => d.id)))];

		//子节点如果是选中状态，则默认父节点也是选中
		authCheckedKeys.value.checked = [...new Set(authCheckedKeys.value.checked.concat(node.parent_ids.split(',').map((id) => parseInt(id))))];
	} else {
		authCheckedKeys.value.checked = authCheckedKeys.value.checked.filter((d) => !nodes.map(({ id }) => id).includes(d));
	}
}
</script>

<style scoped lang="scss">
.toolbar {
	padding: 12px;
	background: #fff;

	.ant-form {
		position: relative;
		margin-bottom: -24px;
	}
}
</style>